package org.example.journal_items.service.impl;

import org.example.journal_items.Entity.Diary;
import org.example.journal_items.Repository.DiaryRepository;
import org.example.journal_items.service.DiaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import jakarta.persistence.EntityNotFoundException;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Service
public class DiaryServiceImpl implements DiaryService {
  private static final Logger logger = LoggerFactory.getLogger(DiaryServiceImpl.class);

  @Autowired
  private DiaryRepository diaryRepository;

  @Override
  public Page<Diary> getDiariesByUserId(Long userId, int page, int size) {
    Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending());
    return diaryRepository.findByUserId(userId, pageable);
  }

  @Override
  public Diary getDiaryById(Long id) {
    return diaryRepository.findById(id)
        .orElseThrow(() -> new EntityNotFoundException("Diary not found with id: " + id));
  }

  @Override
  public Diary createDiary(Diary diary) {
    // 确保创建时间和更新时间设置为当前时间
    Date now = new Date();
    diary.setCreatedAt(now);
    diary.setUpdatedAt(now);

    return diaryRepository.save(diary);
  }

  @Override
  public Diary updateDiary(Long id, Diary diaryDetails) {
    Diary diary = getDiaryById(id);
    diary.setTitle(diaryDetails.getTitle());
    diary.setContent(diaryDetails.getContent());
    diary.setMood(diaryDetails.getMood());
    diary.setWeather(diaryDetails.getWeather());
    diary.setIsPrivate(diaryDetails.getIsPrivate());
    diary.setPrivatePassword(diaryDetails.getPrivatePassword());

    // 更新图片字段
    if (diaryDetails.getImages() != null) {
      diary.setImages(diaryDetails.getImages());
    }

    // Do not update favorite status here, use toggleFavorite
    return diaryRepository.save(diary);
  }

  @Override
  public void deleteDiary(Long id) {
    diaryRepository.deleteById(id);
  }

  @Override
  public Diary toggleFavorite(Long id) {
    Diary diary = getDiaryById(id);
    diary.setIsFavorite(!diary.getIsFavorite());
    return diaryRepository.save(diary);
  }

  @Override
  public long countTotalDiariesByUserId(Long userId) {
    return diaryRepository.countByUserId(userId);
  }

  @Override
  public long getConsecutiveDaysByUserId(Long userId) {
    List<Date> dates = diaryRepository.findDistinctCreationDatesByUserId(userId);
    if (dates == null || dates.isEmpty()) {
      return 0;
    }

    // Get a sorted list of unique dates
    List<LocalDate> uniqueSortedDates = dates.stream()
        .map(d -> d.toInstant().atZone(ZoneId.systemDefault()).toLocalDate())
        .distinct()
        .sorted()
        .collect(Collectors.toList());

    if (uniqueSortedDates.isEmpty()) {
      return 0;
    }

    long longestStreak = 0;
    long currentStreak = 0;

    // Check if there's at least one diary
    if (!uniqueSortedDates.isEmpty()) {
      longestStreak = 1;
      currentStreak = 1;
    }

    for (int i = 1; i < uniqueSortedDates.size(); i++) {
      LocalDate currentDate = uniqueSortedDates.get(i);
      LocalDate previousDate = uniqueSortedDates.get(i - 1);

      if (currentDate.isEqual(previousDate.plusDays(1))) {
        currentStreak++;
      } else {
        currentStreak = 1; // Reset streak
      }

      if (currentStreak > longestStreak) {
        longestStreak = currentStreak;
      }
    }

    return longestStreak;
  }

  @Override
  public List<Diary> getPrivateDiaries(Long userId) {
    return diaryRepository.findByUserIdAndIsPrivateTrueOrderByCreatedAtDesc(userId);
  }
}